<?php

namespace Plugin\File\Service;

use Common\Common;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Tts\V20190823\TtsClient;
use TencentCloud\Tts\V20190823\Models\TextToVoiceRequest;

require_once BASE_PATH . '/extend/tencent/vendor/autoload.php';

class VoiceService
{
    /**
     * 获取音频
     * @param $params
     * @return string
     */
    public static function saveVoice($params): string
    {
        // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
        // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
        // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
        $configs = Common::getConfigByGroup('TencentCloud');
        $cred = new Credential($configs['secret_id']['value'], $configs['secret_key']['value']);
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        $httpProfile = new HttpProfile();
        $httpProfile->setEndpoint("tts.tencentcloudapi.com");

        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        $clientProfile = new ClientProfile();
        $clientProfile->setHttpProfile($httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        $client = new TtsClient($cred, "ap-chengdu", $clientProfile);

        // 实例化一个请求对象,每个接口都会对应一个request对象
        $req = new TextToVoiceRequest();
        $req->fromJsonString(json_encode($params));
        // 返回的resp是一个TextToVoiceResponse的实例，与请求对象对应
        $resp = $client->TextToVoice($req);
        // 输出json格式的字符串回包
        $resp = json_decode($resp->toJsonString(), true);
        // 解码 Base64 字符串为二进制数据
        $audioData = base64_decode($resp['Audio']);
        $date = date('Ymd');
        $directory = self::getVoiceBasePath() . 'voice/' . $date;
        if (!file_exists($directory)) mkdir($directory, 0775, true);

        // 创建一个新的文件来保存音频数据
        $filename = md5(json_encode($params) . time()) . '_audio.wav'; // 文件名可以自定义，根据需要修改后缀名
        // 写入音频数据到文件
        file_put_contents($directory . '/' . $filename, $audioData);

        return 'voice/' . $date . '/' . $filename;
    }

    public static function getVoiceBasePath(): string
    {
        return BASE_PATH . '/storage/';
    }
    
    /**
     * 计算音频时长
     * @param string $audioPath 音频文件路径
     * @return float 音频时长，精确到两位小数
     */
    public static function getAudioDuration(string $audioPath): float
    {
        // 如果路径不是绝对路径，则拼接基础路径
        if (!file_exists($audioPath)) {
            $audioPath = self::getVoiceBasePath() . $audioPath;
        }
        
        // 检查文件是否存在
        if (!file_exists($audioPath)) {
            return 0;
        }
        
        // 使用ffmpeg获取音频时长
        $command = 'ffmpeg -i "' . $audioPath . '" 2>&1 | grep "Duration" | cut -d " " -f 4 | sed s/,//';
        $output = shell_exec($command);
        
        if (empty($output)) {
            return 0;
        }
        
        // 解析时长格式 00:00:00.00
        $timeParts = explode(':', trim($output));
        if (count($timeParts) !== 3) {
            return 0;
        }
        
        // 计算总秒数
        $hours = (float)$timeParts[0];
        $minutes = (float)$timeParts[1];
        $seconds = (float)$timeParts[2];
        $totalSeconds = $hours * 3600 + $minutes * 60 + $seconds;
        
        // 返回精确到两位小数的时长
        return round($totalSeconds, 2);
    }
}